
interface ILinkedListNode {
  value: number;
  next: ILinkedListNode | null;
}

/**
 * 我是一个链表类
 */
class LinkedList {
  head: ILinkedListNode = LinkedList.createNode(0);
  tail: ILinkedListNode = this.head;
  static createNode(value: number) {
    const node: ILinkedListNode = {
      value: value,
      next: null,
    };
    return node;
  }


  // 在尾部添加节点
  add(value: number) {
    // 创建节点,追加到尾部，更新head和tail
    const newNode = LinkedList.createNode(value);
    this.tail.next = newNode;
    this.tail = newNode;
  }
  // 在初始位置添加节点
  prepend(value: number) {
    // 创建节点，追加到开始位置，更新head和tail
    const newNode = LinkedList.createNode(value);
    newNode.next = this.head;
    this.head = newNode;
  }
  // 在指定位置添加节点
  insert(idx: number, value: number) {
    const newNode = LinkedList.createNode(value);
    let curr = this.head;
    for (let i = 0; i < idx - 1; i++) {
      // 把下一个赋值给上一个
      if (curr.next) {
        curr = curr.next;
      }
    }
    // 把新元素赋值给当前的下一个指向，把当前的下一个赋值给新元素的next，这样就连接起来了
    [curr.next, newNode.next] = [newNode, curr.next];
    // 分析：
    // curr: 1-2-3
    // newNode: 99
    // newNode赋值给curr.next, curr:1-99
    // curr.next是2-3,赋值给newNode.next,newNode: 99-2-3
    // curr和newNode已经合并了: 1-99-2-3
  }

  // 删除指定位置的节点
  remove(idx: number) {
    let curr = this.head;
    let target: ILinkedListNode | null = null;
    for (let i = 0; i < idx - 1; i++) {
      // 把下一个赋值给上一个
      if (curr.next) {
        curr = curr.next;
        target = curr.next;
      }
    }
    if (curr.next) {
      curr.next = curr.next.next;
    }
    return target;
  }
  // 反转链表
  reverse() {
    let head = this.head;
    if (head === null || head.next === null) {
      return head;
    }
    let first: ILinkedListNode | null = null;
    while (head) {
      const temp = head.next!;
      // 把节点向前推一个
      ;;[head.next, first,  head] =
        // ↑          ↑       ↑
        [first,     head,   temp];

      /**
       * 分析：
       *
       * 第一轮：
       * 暂存除去第一个节点{0,}的head剩余部分，设为temp：{1,{2,{3,null}}}
       * 第一次赋值：拿到初始节点head：{0,first} 即 {0,null}
       * 第二次赋值：把前一部分(first)设为当前head（{0,null}）
       * 第三次赋值：把当前head更新为temp：{1,{2,{3,null}}}
       *
       * 第二轮：
       * 暂存除去第一个节点{1,}的head剩余部分，设为temp：{2,{3,null}}
       * 第一次赋值：拿到初始节点head：{1,first} 即 {1,{0,null}}
       * 第二次赋值：把前一部分(first)设为当前head（{1,{0,null}}）
       * 第三次赋值：把当前head更新为temp：{2,{3,null}}
       *
       * 第三轮：
       * 暂存除去第一个节点{2,}的head剩余部分，设为temp：{3,null}
       * 第一次赋值：拿到初始节点head：{2,first} 即 {2,{1,{0,null}}}
       * 第二次赋值：把前一部分(first)设为当前head（{2,{1,{0,null}}}）
       * 第三次赋值：把当前head更新为temp：{3,null}
       *
       * 第四轮：
       * 暂存除去第一个节点{3,}的head剩余部分，设为temp：null
       * 第一次赋值：拿到初始节点head：{3,first} 即 {3,{2,{1,{0,null}}}}
       * 第二次赋值：把前一部分(first)设为当前head（{3,{2,{1,{0,null}}}}）
       * 第三次赋值：把当前head更新为temp：null
       *
       * 第五轮：
       * head的值为null，判断为false，循环结束
       * ！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！
       * 搞会了！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！1
       */

    }
    return first;
  }
}

const linkedList = new LinkedList();
linkedList.add(1);
linkedList.add(2);
linkedList.add(3);
console.log('【add】', linkedList.head);
linkedList.insert(2, 99);
console.log('【insert】', linkedList.head);
linkedList.remove(2);
console.log('【remove】', linkedList.head);
const reverseLink = linkedList.reverse();
console.log('【reverse】', reverseLink);


